package netaddr;

import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.thread.ThreadFactoryBuilder;
import util.RemoteSSH;
import util.UnlockQueue;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.*;

public class NetAddr {
    private static ExecutorService executorService;
    static {
        executorService = Executors.newFixedThreadPool(10, new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r);
            }
        });
    }
    static class task1 implements Callable {
        private InetAddress ia;
        public task1(InetAddress ia){
            this.ia = ia;
        }
        @Override
        public Boolean call() {
            try {
                if(ia.isLoopbackAddress())return false;
                if(ia.isAnyLocalAddress())return false;
                if(ia.isLinkLocalAddress())return false;
                if(ia.isMulticastAddress())return false;
                if(ia.isMCGlobal())return false;
                if(ia.isMCLinkLocal())return false;
                if(ia.isMCNodeLocal())return false;
                if(ia.isMCOrgLocal())return false;
                if(ia.isMCSiteLocal())return false;
                String canonicalHostName = ia.getCanonicalHostName();
                //System.out.println("canonicalHostName : "+canonicalHostName);//来自/etc/hosts文件
                boolean reachable = ia.isReachable(100);
                return Boolean.valueOf(reachable);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Boolean.FALSE;
        }
    }
    static class task2 implements Runnable{
//        ConcurrentSkipListMap<InetAddress,Future> map = new ConcurrentSkipListMap<>();
        UnlockQueue<KeyValuePair> map = new UnlockQueue<KeyValuePair>();

        public void add(String inetAddress,Future furture ){
            KeyValuePair<String, Future> inetAddressFutureKeyValuePair = new KeyValuePair<>(inetAddress, furture);
            map.add(inetAddressFutureKeyValuePair);
        }
        @Override
        public void run() {
            boolean break_flag = false;
            while (true){
                UnlockQueue.Entry entry = map.next();
                if(entry == null){
                    continue;
                }
                KeyValuePair<String, Future<Boolean>> value = (KeyValuePair) entry.getValue();
                try {
                    if(value.getValue().isDone()){
                        Boolean o = value.getValue().get();
                        if(o == true){
                            System.out.println(value.getKey() + " is reachable : " + o);
                            try {
                                String hostname = RemoteSSH.execRemoteCommand(
                                        value.getKey(),
                                        "root",
                                        "hadoop",
                                        "hostname",
                                        100);
                                System.out.println("hostname : " + hostname);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        }
                        map.remove(entry);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break_flag = true;

                } catch (ExecutionException e) {
                    break_flag = true;
                }
                if(break_flag && map.size() <= 0){
                    break;
                }
            }
        }
    }
    public static void main(String[] args) throws IOException {

        try {
//            InetAddress byName = InetAddress.getByName("192.168.150.141");
//
//            System.out.println(byName.isReachable(100));




            task2 task2 = new task2();
            executorService.execute(task2);
            List<String> list = Ipv4Util.list("192.168.150.0", 24, true);
            for (String s : list) {
//                System.out.print(s + " is reacheable : ");
//                System.out.println(InetAddress.getByName(s).isReachable(10));

                InetAddress byName1 = InetAddress.getByName(s);
                Future submit = executorService.submit(new task1(byName1));
                task2.add(s,submit);
            }

            /*InetAddress[] allByName = InetAddress.getAllByName("192.168.150.141/24");
            for (InetAddress inetAddress : allByName) {
                System.out.println(inetAddress.isReachable(100));
            }*/
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }finally {

        }
    }
}
